package liportest.ability;

import liportest.model.OrderModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.persist.DefaultStateMachinePersister;
import org.springframework.statemachine.support.DefaultStateMachineContext;

import java.util.EnumSet;

@Configuration
@EnableStateMachine(name = "abilityStateMachine")
public class AbilityStateMachineConfig extends StateMachineConfigurerAdapter<AbilityStatus,AbilityChangeEvent>{

    public void configure(StateMachineStateConfigurer<AbilityStatus, AbilityChangeEvent> config) throws Exception {
        config.withStates().initial(AbilityStatus.WRITED).states(EnumSet.allOf(AbilityStatus.class));
    }

    public void configure(StateMachineTransitionConfigurer<AbilityStatus, AbilityChangeEvent> config) throws Exception {
        config.withExternal().source(AbilityStatus.WRITED).target(AbilityStatus.UNAPPROVE).event(AbilityChangeEvent.SUBMIT_APPROVE)
                .and()
                .withExternal().source(AbilityStatus.UNAPPROVE).target(AbilityStatus.UNPUBLISHED).event(AbilityChangeEvent.APPROVE_PASS)
                .and()
                .withExternal().source(AbilityStatus.UNAPPROVE).target(AbilityStatus.WRITED).event(AbilityChangeEvent.APPROVE_REJECT)
                .and()
                .withExternal().source(AbilityStatus.UNPUBLISHED).target(AbilityStatus.PUBLISHED).event(AbilityChangeEvent.PUBLISH)
                .and()
                .withExternal().source(AbilityStatus.PUBLISHED).target(AbilityStatus.UNPUBLISHED).event(AbilityChangeEvent.OFFLINE);
    }

    /**
     * 持久化配置
     * 实际使用中，可以配合redis等，进行持久化操作
     *
     * @return
     */
    @Bean
    public DefaultStateMachinePersister persister() {
        return new DefaultStateMachinePersister<>(new StateMachinePersist<Object, Object, OrderModel>() {
            @Override
            public void write(StateMachineContext<Object, Object> context, OrderModel order) throws Exception {
                //此处并没有进行持久化操作
            }

            @Override
            public StateMachineContext<Object, Object> read(OrderModel order) throws Exception {
                //此处直接获取order中的状态，其实并没有进行持久化读取操作
                return new DefaultStateMachineContext(order.getStatus(), null, null, null);
            }
        });
    }
}
